home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / diskutil / partcopy.lzh / HARD.C next >
C/C++ Source or Header  |  1988-12-13  |  7KB  |  404 lines

  1. /*
  2.  * new version with multiple LUN support
  3.  *
  4.  */
  5.  
  6. #include <portab.h>
  7. #include <osbind.h>
  8.  
  9. #define NEW 1    /* support multiple LUN code */
  10. #define OLD 0    /* support the old version   */
  11.  
  12. /********************************************************/
  13. /*                                                      */
  14. /* SUPRA CORPORATION                                    */
  15. /*    Hard Disk drivers for the Atari 520 ST            */
  16. /*                                                      */
  17. /* 1 July 1986                                          */
  18. /*                                                      */
  19. /*                                                      */
  20. /********************************************************/
  21.  
  22.  
  23. /********************************************************/
  24. /*   PART 2                                             */
  25. /*                                                      */
  26. /*        Actual low level routines to access a dma     */
  27. /*        device.  These routines are also compatible   */
  28. /*        with the Atari hard disk drives               */
  29. /*                                                      */
  30. /********************************************************/
  31.  
  32. WORD *flock      = 0x43eL;
  33. BYTE *gpip       = 0xfffa01L;
  34. WORD *diskctl_w  = 0xff8604L;
  35. LONG *diskctl_l  = 0xff8604L;
  36. WORD *fifo       = 0xff8606L;
  37. BYTE *dmahigh    = 0xff8609L;
  38. BYTE *dmamid     = 0xff860bL;
  39. BYTE *dmalow     = 0xff860dL;
  40.  
  41. LONG save_ssp;
  42.  
  43. LONG luns[] = {
  44.         0x00000000L,        /* unit 0 */
  45.         0x00200000L        /* unit 1 */
  46.     } ;
  47.  
  48. #define   READY     0x0008aL
  49. #define   ZERO      0x1008aL
  50. #define   SENSE     0x3008aL
  51. #define   READ      0x8008aL
  52. #define   WRITE     0xa008aL
  53.  
  54. #define   LONG_DELAY  690000L
  55. #define   SHORT_DELAY 23000L
  56. #define   V_SHORT_DLY 500L
  57. #define   FLOCK_ON    -1
  58. #define   FLOCK_OFF   0
  59.  
  60. extern VOID end_hd();
  61.  
  62. VOID
  63. sup_on()
  64. {
  65.     save_ssp = Super(0L);
  66. }
  67.  
  68. VOID
  69. sup_off()
  70. {
  71.     Super(save_ssp);
  72. }
  73.  
  74. WORD
  75. wait(time)
  76. LONG time;
  77. {
  78.  
  79.     while(time--) {
  80.         if( (*gpip & 0x20) == 0)
  81.             return(0);
  82.     }         
  83.     return(-1);
  84. }
  85.  
  86. VOID
  87. fifo_rd(count)
  88. WORD count;
  89. {
  90.     long zero = 0L;
  91.  
  92.     *fifo = 0x90;
  93.     *fifo = 0x190;
  94.     *fifo = 0x90;
  95.     *diskctl_w = count;
  96.     *fifo = 0x8a;
  97.     *diskctl_l = zero; /* this forces a move not a clr */
  98. }
  99.  
  100. VOID
  101. fifo_wrt(count)
  102. WORD count;
  103. {
  104.  
  105.     *fifo = 0x90;
  106.     *fifo = 0x190;
  107.     *diskctl_w = count;
  108.     *fifo = 0x18a;
  109.     *diskctl_l = 0x100L;
  110. }
  111.  
  112. #if OLD
  113. /* old read: */
  114. WORD
  115. hd_read(sectno,count,buf,dma)
  116. LONG sectno;
  117. WORD count;
  118. LONG buf;
  119. WORD dma;
  120. {
  121.     WORD err;
  122.  
  123.     sup_on();
  124.     err = select_sector(READ,sectno,count,buf,dma,0L); /* goofed */
  125.     if( err == 0 ) {
  126.         fifo_rd(count);
  127.         err = get_status(0x8a);
  128.     }
  129.     end_hd();
  130.     sup_off();
  131.     return(err);
  132. }
  133. #endif
  134.  
  135. #if NEW
  136. WORD
  137. nhd_read(sectno,count,buf,dma,drive)
  138. LONG sectno;
  139. WORD count;
  140. LONG buf;
  141. WORD dma;
  142. WORD drive;    /* 0 or 1 */
  143. {
  144.     WORD err;
  145.  
  146.     sup_on();
  147.     err = select_sector(READ,sectno,count,buf,dma,luns[drive]); /* goofed */
  148.     if( err == 0 ) {
  149.         fifo_rd(count);
  150.         err = get_status(0x8a);
  151.     }
  152.     end_hd();
  153.     sup_off();
  154.     return(err);
  155. }
  156. #endif
  157.  
  158. #if OLD
  159. WORD
  160. hd_write(sectno,count,buf,dma)
  161. LONG sectno;
  162. WORD count;
  163. LONG buf;
  164. WORD dma;
  165. {
  166.     WORD err;
  167.  
  168.     sup_on();
  169.     err = select_sector(WRITE,sectno,count,buf,dma,0L); /* goofed */
  170.     if( err == 0 ) {
  171.         fifo_wrt(count);
  172.         err = get_status(0x18a);
  173.     }
  174.     end_hd();
  175.     sup_off();
  176.     return(err);
  177. }
  178. #endif
  179.  
  180. #if NEW
  181. /* new version */
  182. WORD
  183. nhd_write(sectno,count,buf,dma,drive)
  184. LONG sectno;
  185. WORD count;
  186. LONG buf;
  187. WORD dma;
  188. WORD drive;
  189. {
  190.     WORD err;
  191.  
  192.     sup_on();
  193.     err = select_sector(WRITE,sectno,count,buf,dma,luns[drive]); /* goofed */
  194.     if( err == 0 ) {
  195.         fifo_wrt(count);
  196.         err = get_status(0x18a);
  197.     }
  198.     end_hd();
  199.     sup_off();
  200.     return(err);
  201. }
  202. #endif
  203.  
  204. WORD
  205. get_status(mode)
  206. WORD mode;
  207. {
  208.     WORD err;
  209.  
  210.     err = wait(LONG_DELAY);
  211.     if( !err ) {
  212.         *fifo = mode;
  213.         err = *diskctl_w & 0xff;
  214.     }
  215.     return(err);
  216. }
  217.  
  218. VOID
  219. end_hd()
  220. {
  221.     WORD dummy;
  222.  
  223.     *fifo = 0x80;
  224.     dummy = *diskctl_w;
  225.     *flock    = FLOCK_OFF;
  226. }
  227.  
  228. VOID
  229. set_dma(buf)
  230. LONG buf;
  231. {
  232.  
  233.     *dmalow = (BYTE) (buf & 0xff);
  234.     *dmamid = (BYTE) ((buf >> 8) & 0xff);
  235.     *dmahigh = (BYTE) ((buf >> 16) & 0xff);
  236. }
  237.  
  238.  
  239. WORD
  240. select_sector(command,sectno,count,buf,dma,goofydrive)
  241. LONG command,sectno;
  242. WORD count;
  243. LONG buf;
  244. WORD dma;
  245. LONG goofydrive; /* This is the new drive #, shifted to left 5. */
  246.          /* drive 0 would be 0. drive 1 would be, uh, 32. (0x20) */
  247. {
  248.     WORD err;
  249.  
  250.     *flock = FLOCK_ON;
  251.     if ( buf )
  252.         set_dma(buf);
  253.     *fifo = 0x88;
  254.     *diskctl_l = ( (LONG) dma << 21) | command;
  255.     err = wait(SHORT_DELAY);
  256.     if( !err ) {
  257.         /* 
  258.          * old:
  259.          * *diskctl_l  = ( (LONG) dma << 21) 
  260.          *         | (sectno & 0x1f0000) 
  261.          *         | 0x8a;
  262.          *
  263.          * newer (but still wrong) :
  264.          * *diskctl_l = ( (LONG) dma << 21) 
  265.          *        | (goofydrive & 0xe00000L) 
  266.          *        | (sectno & 0x1f 0000L) 
  267.          *        | 0x8a;
  268.          *
  269.          * The second one (and the first one) BOTH output the SCSI 
  270.          * device number here where it isn't needed.  All that is
  271.          * needed is the unit number. 
  272.          * 
  273.          * NOTE: this means the original SUPRA driver as ul'd
  274.          *       is WRONG if using multiple SCSI devices. 
  275.          *
  276.          * dlm  --- August 3, 1987
  277.          */
  278.         *diskctl_l = (goofydrive & 0xe00000L) 
  279.                  | (sectno & 0x1f0000L) 
  280.                  | 0x8a ;
  281.      
  282.         err = wait(SHORT_DELAY);
  283.         if( !err ) {
  284.             *diskctl_l = (sectno & 0xff00) << 8 | 0x8a;
  285.             err = wait(SHORT_DELAY);
  286.             if( !err ) {
  287.                 *diskctl_l = (sectno & 0xff) << 16 | 0x8a;
  288.                 err = wait(SHORT_DELAY);
  289.                 if( !err ) {
  290.                     *diskctl_l = (LONG) (count & 0xff) <<
  291.                              16 | 0x8a;
  292.                     err = wait(SHORT_DELAY);
  293.                 }
  294.             }
  295.         }
  296.     }
  297.     return(err);
  298. }
  299.  
  300. WORD
  301. send_dcb(count,dma,command,forever)
  302. WORD count,dma,forever;
  303. LONG command;
  304. {
  305.     WORD err;
  306.  
  307.     sup_on();
  308.     err = select_sector(command,0L,count,0L,dma,0L);  /* goofed */
  309.      if ( !err ) {
  310.         *diskctl_l = 0x8aL;
  311.         do {
  312.             err = wait(SHORT_DELAY);
  313.         } while( err && forever );
  314.         err = get_status(0x8a);
  315.     }
  316.     end_hd();
  317.     sup_off();
  318.     return(err);
  319. }
  320.  
  321. WORD
  322. sc_zero(dma)
  323. WORD dma;
  324. {
  325.  
  326.     return( send_dcb(0,dma,ZERO,0) ) ;
  327. }
  328.  
  329. WORD
  330. sc_ready(dma)
  331. WORD dma;
  332. {
  333.  
  334.     return( send_dcb(0,dma,READY,0) ) ;
  335. }
  336.  
  337. WORD
  338. byte_rd(buf,len)
  339. BYTE *buf;
  340. WORD len;
  341. {
  342.     WORD i;
  343.  
  344.     *diskctl_l = 0x8aL;
  345.     wait(SHORT_DELAY);
  346.     i=0;
  347.     while( len ) {
  348.         if( wait(V_SHORT_DLY) == -1 ) {
  349.             buf[i++] =  (BYTE) (*diskctl_w & 0xff);
  350.             len--;
  351.         }
  352.         else
  353.             break;
  354.     }
  355.     wait(SHORT_DELAY);
  356.     return(i);
  357. }
  358.  
  359. #if OLD
  360. WORD
  361. hd_sense(dma,buf,len)
  362. WORD dma,len;
  363. BYTE *buf;
  364. {
  365.     WORD err;
  366.  
  367.     sup_on();
  368.     err = select_sector(SENSE,0L,len,0L,dma,0L); /* goofed */
  369.     if( err == 0 ) {
  370.         byte_rd(buf,len);
  371.         err = get_status(0x8a);
  372.     }
  373.     end_hd();
  374.     sup_off();
  375.  
  376.     return(err);
  377. }
  378. #endif
  379.  
  380. #if NEW
  381. WORD
  382. nhd_sense(dma,buf,len, drive)
  383. WORD dma,len;
  384. BYTE *buf;
  385. WORD drive;
  386. {
  387.     WORD err;
  388.  
  389.     sup_on();
  390.  
  391.     err = select_sector(SENSE,0L,len,0L,dma,luns[drive]); /* goofed */
  392.  
  393.     if( err == 0 ) {
  394.         byte_rd(buf,len);
  395.         err = get_status(0x8a);
  396.     }
  397.  
  398.     end_hd();
  399.     sup_off();
  400.  
  401.     return(err);
  402. }
  403. #endif
  404.